# import cv2
#
#
# def detect_human(frame):
#     """
#     从给定的图像帧中检测人体，并返回检测到的人体边界框。
#     """
#     # 示例中使用OpenCV的预训练Haar级联分类器进行人脸检测
#     # 实际应用中可替换为更高级的人体检测模型
#     haar_file_path = "data/models/haarcascade_fullbody.xml"
#     body_cascade = cv2.CascadeClassifier(haar_file_path)
#     gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#     bodies = body_cascade.detectMultiScale(gray, 1.1, 4)
#     for (x, y, w, h) in bodies:
#         cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
#     return frame

# src/detection.py（修改后）
import cv2
import os
class HumanDetector:
    """人体检测器：只负责找人体位置，返回边界框"""
    def __init__(self):
        # 自动计算模型路径（避免硬编码，适配不同运行环境）
        self.src_dir = os.path.dirname(os.path.abspath(__file__))
        self.root_dir = os.path.dirname(self.src_dir)  # 项目根目录
        self.model_path = os.path.join(self.root_dir, "data", "models", "haarcascade_fullbody.xml")
        self.detector = self._load_model()  # 加载模型

    def _load_model(self):
        """加载Haar模型，失败不崩溃（返回None，后续跳过检测）"""
        if not os.path.exists(self.model_path):
            print(f"警告：未找到人体检测模型！路径：{self.model_path}")
            print("提示：请将haarcascade_fullbody.xml放到data/models文件夹下，否则跳过人体检测")
            return None
        try:
            return cv2.CascadeClassifier(self.model_path)
        except Exception as e:
            print(f"模型加载失败：{e}")
            return None

    def detect(self, frame):
        """
        核心方法：检测人体
        返回：(绘制了边界框的帧, 边界框列表[(x1,y1,x2,y2), ...])
        说明：x1,y1是左上角，x2,y2是右下角；无人体时返回空列表
        """
        if self.detector is None:
            return frame, []  # 模型加载失败，直接返回原帧和空框

        # 转灰度图（Haar检测需要）
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 检测人体（scaleFactor=1.1：缩放系数，minNeighbors=4：过滤误检）
        bodies = self.detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4)
        # 转换格式：(x,y,w,h) → (x1,y1,x2,y2)
        bboxes = [(x, y, x + w, y + h) for (x, y, w, h) in bodies]

        # 绘制边界框（蓝色，线宽2）
        for (x1, y1, x2, y2) in bboxes:
            cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)

        return frame, bboxes